﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GraphViewer.Entity;
using GraphViewer.View;
using System.IO;
using System.Diagnostics;
using System.Configuration;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.Xml;

namespace ExecutionOrder
{
    class Program
    {
        private static List<ProcessEntity> _orderedProcesses;
        private static StringBuilder _messageBuilder;

        private static string _sqlServerName;
        private static string _mtsServerName;
        private static string _dataBase;
        private static bool _agendar;
        private static List<ProcessEntity> _processes = new List<ProcessEntity>();

        static void Main(string[] args)
        {
            _sqlServerName = ConfigurationManager.AppSettings["SQLServerName"];
            _mtsServerName = ConfigurationManager.AppSettings["MTSServerName"];
            _agendar = Convert.ToBoolean(ConfigurationManager.AppSettings["Agendar"]);
            _dataBase = ConfigurationManager.AppSettings["DataBase"];

            //string grupos = Console.ReadLine();

            //ChangeFrameworkClient();

            FormViewer v = new FormViewer();
            //v.ShowCTM = true;
            v.PopulateData(_sqlServerName);
            _orderedProcesses = v.OrderedProcessesSimio;

            foreach (var group in v.OrderedGroupsSimio)
            {
                WriteProcessList(group.GroupId);
            }

            //if (_agendar)
            //{
            //    ExecuteProcess(null, true);
            //}

            //Open();

            //foreach (var group in v.OrderedGroupsSimio)
            //{
            //    ExecuteGroup(group.GroupId);
            //}

            //ExecuteGroup(_orderedProcesses.Where(p => p.GroupId == "3"));

            //ExecuteGroup(1);
            //ExecuteGroup(2);
            //ExecuteGroup(5);
            //ExecuteGroup("3");
            //ExecuteGroup("4");
            //ExecuteGroup(6);
            //ExecuteGroup(16);
            //ExecuteGroup("17");
            //ExecuteGroup("20");
            //ExecuteGroup(21);
        }

        private static void WriteProcessList(string groupId)
        {
            if (File.Exists(@"c:\processos_grupo_" + groupId + ".bat"))
                File.Delete(@"c:\processos_grupo_" + groupId + ".bat");

            //if (File.Exists(@"c:\processos.bat"))
            //    File.Delete(@"c:\processos.bat");

            foreach (var process in _orderedProcesses.Where(p => p.GroupId == groupId && p.TaskType == "Job"))
            {
                
                //File.AppendAllText(@"c:\processos_grupo_" + groupId + ".txt", process.ProcessId + System.Environment.NewLine);
                //File.AppendAllText(@"c:\processos_grupo_" + groupId + ".txt", process.ProcessId.ToString().PadRight(10) + process.ProcessName.ToString() + System.Environment.NewLine);
                //File.AppendAllText(@"c:\processos_grupo_" + groupId + ".txt", process.GroupId.ToString().PadRight(10) + process.ProcessId.ToString().PadRight(10) + Environment.NewLine);
                File.AppendAllText(@"c:\processos_grupo_" + groupId + ".bat", @"\\" + _mtsServerName + @"\Componentes\dotnet\SRC\ibba.src.console.exe -servidor:" + _mtsServerName + " -tipo:comando -id:" + process.ProcessId + " -ref:" + _dataBase + System.Environment.NewLine);
                //File.AppendAllText(@"c:\processos_grupo_" + groupId + ".txt", @"\\BBAGMMTSATI1\Componentes\dotnet\SRC\ibba.src.console.exe -servidor:BBAGMMTSATI1 -tipo:comando -id:" + process.ProcessId + " -ref:" + _dataBase + System.Environment.NewLine);
                //File.AppendAllText(@"c:\processos_grupo_" + groupId + ".bat", "pause" + System.Environment.NewLine);
                //File.AppendAllText(@"c:\processos_grupo_" + groupId + ".bat", System.Environment.NewLine);
                //File.AppendAllText(@"c:\processos.txt", process.GroupId.ToString().PadRight(10) + process.ProcessId.ToString().PadRight(10) + Environment.NewLine);
            }
        }

        private static void ExecuteGroup(string groupId)
        {
            foreach (var process in _orderedProcesses.Where(p => p.GroupId == groupId))
            {
                if (_processes.Find(p => p.ProcessId == process.ProcessId) == null)
                {
                    int seed = 0;
                    int.TryParse(process.ProcessId, out seed);

                    if (seed != 0)
                    {
                        if (ExecuteProcess(process, false) != 0)
                        {
                            Console.ReadKey();
                        }

                        Save();
                    }
                }
            }
        }

        private static int ExecuteProcess(ProcessEntity process, bool schedule)
        {
            System.Diagnostics.Process p = new System.Diagnostics.Process();
            p.StartInfo.FileName = @"\\" + _mtsServerName + @"\Componentes\dotnet\SRC\ibba.src.console.exe";

            if (schedule)
            {
                p.StartInfo.Arguments = @"-servidor:" + _mtsServerName + " -tipo:agendar -sistema:1 -ref:" + _dataBase;
            }
            else
            {
                p.StartInfo.Arguments = @"-servidor:" + _mtsServerName + " -tipo:comando -id:" + process.ProcessId + " -ref:" + _dataBase;
            }

            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.RedirectStandardOutput = true;

            _messageBuilder = new StringBuilder();

            p.ErrorDataReceived += new DataReceivedEventHandler(p_ErrorDataReceived);
            p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);

            p.Start();

            p.BeginOutputReadLine();
            p.BeginErrorReadLine();

            if (!schedule) Console.WriteLine("Executando Processo: " + process.ProcessId.ToString() + " do Grupo: " + process.GroupId.ToString());

            p.WaitForExit();

            if (!schedule) _processes.Add(process);

            if (p.ExitCode != 0)
            {
                if (!schedule)
                {
                    File.AppendAllText(@"c:\erro.txt", process.GroupId.ToString().PadRight(10) + process.ProcessId.ToString().PadRight(10) + System.Environment.NewLine);
                    File.AppendAllText(@"c:\erro.txt", _messageBuilder.ToString() + System.Environment.NewLine);
                    File.AppendAllText(@"c:\erro.txt", System.Environment.NewLine);
                }

                Console.WriteLine(System.Environment.NewLine);
                Console.WriteLine("Problema no processo: ");
                Console.WriteLine(_messageBuilder.ToString());
            }

            return p.ExitCode;
        }

        static void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            _messageBuilder.AppendLine(e.Data);
        }

        static void p_ErrorDataReceived(object sender, DataReceivedEventArgs e)
        {

        }

        public static void Save()
        {
            XDocument document = new XDocument();
            XmlSerializer s = new XmlSerializer(typeof(List<ProcessEntity>));
            XmlWriter writer = document.CreateWriter();
            s.Serialize(writer, _processes);
            writer.Close();
            document.Save(@"execucao.xml");
        }

        public static void Open()
        {
            if (File.Exists(@"execucao.xml"))
            {
                XDocument document = XDocument.Load(@"execucao.xml");
                XmlSerializer s = new XmlSerializer(typeof(List<ProcessEntity>));
                XmlReader reader = document.CreateReader();
                _processes = (List<ProcessEntity>)s.Deserialize(reader);
                reader.Close();
            }
        }

        private static void ChangeFrameworkClient()
        {
            string file = @"C:\FWKBBA\v2.0\Client\bba.framework.remote.client.dll.config";

            if (!File.Exists(file))
                throw new FileNotFoundException(file);

            XDocument document = XDocument.Load(file);
            var element = XElement.Parse(string.Format("<chave sistema=\"RiscoCredito\" local=\"LOCAL\" valor=\"tcp://{0}:11333\" canal=\"tcp\" />", _mtsServerName));

            var node = document.Descendants().ToList().Find(e => e.Name.LocalName == "chave" && e.Attributes().Any(a => a.Name.LocalName == "sistema" && a.Value == "RiscoCredito"));
            node.Remove();

            var appSettings = document.Descendants().ToList().Find(e => e.Name.LocalName == "appSettings");
            appSettings.Add(element);

            document.Save(file);
        }
    }
}
